package com.cmb;

import com.cryptape.cita.crypto.sm2.SM2;
import com.cryptape.cita.crypto.sm2.SM2KeyPair;
import com.cryptape.cita.crypto.sm2.SM2Keys;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;

/**
 * @author CMB
 */
public class SM2Algo {

    private static final SM2 SM2_INSTANCE = new SM2();
    private static final SM2KeyPair KEY_INSTANCE = SM2_INSTANCE.generateKeyPair();

    public static KeyInfo newKeyPair() {
        SM2KeyPair keyPair = SM2_INSTANCE.generateKeyPair();
        KeyInfo keyInfo = new KeyInfo();
        keyInfo.publicKey =
            ByteUtils.toHexString(keyPair.getPublicKey().getEncoded(false)).toUpperCase();
        keyInfo.privateKey = keyPair.getPrivateKey().toString(16).toUpperCase();
        // 通过公钥计算区块链地址
        keyInfo.address = "0x" + SM2Keys.getAddress(keyPair.getPublicKey());

        return keyInfo;
    }

    /**
     * 公钥加密
     *
     * @param plainText 明文
     * @return 密文
     */
    public static byte[] encrypt(String plainText) {
        return SM2_INSTANCE.encrypt(plainText, KEY_INSTANCE.getPublicKey());
    }

    /**
     * 私钥解密
     *
     * @param cipherText 密文
     * @return 明文
     */
    public static String decrypt(byte[] cipherText) {
        return SM2_INSTANCE.decrypt(cipherText, KEY_INSTANCE.getPrivateKey());
    }

    /**
     * 私钥签名
     *
     * @param data 原始数据
     * @return 签名
     */
    public static SM2.Signature sign(String data) {
        return SM2_INSTANCE.sign(data.getBytes(), "1324567890", KEY_INSTANCE);
    }

    /**
     * 公钥验签
     *
     * @param data 原始数据
     * @param sign 签名值
     * @return 成功/失败
     */
    public static boolean verify(String data, SM2.Signature sign) {
        return SM2_INSTANCE
            .verify(data.getBytes(), sign, "1324567890", KEY_INSTANCE.getPublicKey());
    }

    /**
     * 私钥签名(新的) -固定私钥方式
     *
     * @param data 原始数据
     * @return 签名
     */
    public static SM2.Signature sign(byte[] data, String privateKey) {
        return SM2_INSTANCE.sign(data, "1234567812345678", SM2_INSTANCE.fromPrivateKey(privateKey));
    }

    /**
     * 公钥验签（新的）-固定私钥方式
     *
     * @param data 原始数据
     * @param sign 签名值
     * @return 成功/失败
     */
    public static boolean verify(byte[] data, SM2.Signature sign, String privateKey) {
        return SM2_INSTANCE
                .verify(data, sign, "1234567812345678", SM2_INSTANCE.fromPrivateKey(privateKey).getPublicKey());
    }

}
